package com.kitty.common.utils;

import com.kitty.game.attribute.AttrService;
import com.kitty.game.attribute.config.Attribute;
import com.kitty.game.bag.message.RespIconCartoon;
import com.kitty.game.config.Equip;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.equip.message.RespFlyInfo;
import com.kitty.game.equip.model.*;
import com.kitty.game.role.model.Role;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.FormulaUtil;
import com.kitty.mina.message.MessagePusher;
import lombok.extern.slf4j.Slf4j;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;

import java.util.*;
@Slf4j
public class EquipUtil {
    //protected static Logger logger = LoggerFunction.GIFT.getLogger();

    /**
     * 武器能出现的属性ID
     */
    public static final List<Integer> Weapons = Arrays.asList(2, 808, 4, 5, 9, 13, 45, 46, 47, 48, 49, 77, 78, 79, 169, 221, 224);
    /**
     * 头能出现的属性ID
     */
    public static final List<Integer> Hats = Arrays.asList(2, 5, 7, 8, 9, 12, 13, 67, 69, 80, 220);
    /**
     * 衣服能出现的属性ID
     */
    public static final List<Integer> Clothes = Arrays.asList(2, 5, 7, 8, 9, 12, 13, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 69, 80, 85, 220, 222, 223);
    /**
     * 鞋子能出现的属性ID
     */
    public static final List<Integer> Shoes = Arrays.asList(2, 5, 8, 9, 13, 14, 69, 67, 80, 220);

    /**
     * 首饰的强力属性
     */
    public static final List<Integer> attPerfect = Arrays.asList(221,224,2,9,13);
    /**
     * 玉佩属性
     */
    private static final List<Integer> Jade = Arrays.asList(221, 50, 51, 52, 53, 59, 56, 57, 58, 60, 222, 223, 2, 5, 9, 13, 224, 50, 51, 52, 53, 59, 56, 57, 58, 60, 222, 223, 2, 5, 9, 13, 224);
    /**
     * 项链属性
     */
    private static final List<Integer> Necklace = Arrays.asList(221, 50, 51, 52, 53, 59, 56, 57, 58, 60, 222, 223, 2, 5, 9, 13, 224, 50, 51, 52, 53, 59, 56, 57, 58, 60, 222, 223, 2, 5, 9, 13, 224);
    /**
     * 手镯属性
     */
    private static final List<Integer> Bracelet = Arrays.asList(221, 2, 5, 9, 13, 168, 169, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 224,2, 5, 9, 13, 168, 169, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 224);

    /**
     * 改造成功之后添加属性
     */
    public static void addUpgradeField(Equip equip, RoleEquip roleEquip) {
        RoleEquipField roleEquipField = roleEquip.getFields().get((short) 6914);
        if (roleEquipField != null && roleEquipField.getField() != null) {
            for (Map.Entry<Short, FiedValue> entry : roleEquipField.getField().entrySet()) {
                setResonanceField(equip, entry, roleEquip.queryUpgradeLevel());
            }
        }
        LinkedHashMap<Short, RoleEquipField> hashMap = calcAttribOneKey(roleEquip.queryLevel(), roleEquip.queryUpgradeLevel(), roleEquip.queryEquipPos(false), false);
        hashMap.forEach((key, equipField) -> roleEquip.getFields().put(key, equipField));
    }

    /**
     * 刷新装备
     */
    public static void refreshRoleEquip(Role role, RoleEquip roleEquip) {
        ArrayList<RoleEquip> roleEquips = new ArrayList<>();
        roleEquips.add(roleEquip);
        RespFlyInfo respEquipInfo = getEquipInfo(roleEquips);
        MessagePusher.pushMessage(role, respEquipInfo);
    }

    /**
     * 取物品信息封包
     */
    public static RespFlyInfo getEquipInfo(List<RoleEquip> roleEquips) {
        RespFlyInfo respEquipInfo = new RespFlyInfo();
        ArrayList<EquipInfo> equipInfos = new ArrayList<>();
        for (RoleEquip roleEquip : roleEquips) {
            if (roleEquip.getPosition() >= 201) {
                continue;
            }
            EquipInfo equipInfo = new EquipInfo();
            equipInfo.setPosition((byte) roleEquip.getPosition());
            equipInfo.setEquipFields(transferList(roleEquip.getFields()), transferList2(roleEquip.getHunQiFields()));
            equipInfos.add(equipInfo);

        }
        respEquipInfo.setList(equipInfos);
        return respEquipInfo;
    }

    /**
     * 取物品属性信息
     */
    public static List<EquipField> transferList(LinkedHashMap<Short, RoleEquipField> linkedHashMap) {
        List<EquipField> equipFields = new ArrayList<>();
        if (linkedHashMap == null) {
            return equipFields;
        }
        for (Map.Entry<Short, RoleEquipField> entry : linkedHashMap.entrySet()) {
            EquipField equipField = new EquipField();
            equipField.setType(entry.getKey());
            RoleEquipField roleEquipField = entry.getValue();
            if (roleEquipField == null || roleEquipField.getField() == null) {
                continue;
            }

            List<FiedValue> fiedValues = new ArrayList<>(roleEquipField.getField().values());
            equipField.setFieldValues(fiedValues);
            equipFields.add(equipField);
        }
        return equipFields;
    }

    /**
     * 取物品属性信息
     */
    public static List<RoleHunQiField> transferList2(LinkedHashMap<Short, RoleHunQiField> linkedHashMap) {
        List<RoleHunQiField> equipFields = new ArrayList<>();
        if (linkedHashMap == null) {
            return equipFields;
        }
        for (Map.Entry<Short, RoleHunQiField> entry : linkedHashMap.entrySet()) {
            equipFields.add(entry.getValue());
        }

        return equipFields;
    }

    /**
     * 添加物品
     */
    public static void add(Role role, RoleEquip roleEquip) {
        EquipBox equipBox = role.getEquipBox();
        equipBox.addEquip(roleEquip);
    }

    /**
     * 取装备基础属性
     */
    public static LinkedHashMap<Short, FiedValue> getBasicAttrNew(Equip equip, RoleEquip roleEquip, String color, boolean isIdentify) {
        LinkedHashMap<Short, FiedValue> linkedHashMap = new LinkedHashMap<>();
        List<FiedValue> values = new ArrayList<>();
        if (equip.getPosition() >= 4 && equip.getPosition() <= 6) {
            values.add(new FiedValue(452, 0));//首饰转换限制时间
            values.add(new FiedValue(451, 0));//首饰转换次数
            if (equip.getReq_level() < 80) {//小于80级能叠加
                values.add(new FiedValue(282, 2));//能否叠加
            }
        }
        values.add(new FiedValue(889, 0));
        values.add(new FiedValue(205, equip.getReq_level()));
        values.add(new FiedValue(203, 1));//
        values.add(new FiedValue(269, 0));//套装相性
        values.add(new FiedValue(74, 1));//物品类型
        values.add(new FiedValue(34, 0));
        values.add(new FiedValue(807, 0));
        values.add(new FiedValue(276, 0));
        values.add(new FiedValue(31, equip.getReq_level()));
        values.add(new FiedValue(198, 0));//改造完成度
        values.add(new FiedValue(44, equip.getMenpai()));
        values.add(new FiedValue(202, equip.getPosition()));
        values.add(new FiedValue(40, equip.getIcon()));
        values.add(new FiedValue(207, equip.getValue() * 5));//出手价格
        values.add(new FiedValue(208, 0));
        values.add(new FiedValue(1, equip.getKey_name()));
        values.add(new FiedValue(306, String.valueOf(roleEquip.getId())));
        values.add(new FiedValue(815, 0));
        values.add(new FiedValue(271, 0));
        values.add(new FiedValue(296, 0));
        values.add(new FiedValue(881, 0));
        values.add(new FiedValue(209, color));
        values.add(new FiedValue(84, roleEquip.getId()));
        values.add(new FiedValue(270, 0));
        values.add(new FiedValue(268, 0));//套装相性
        values.add(new FiedValue(197, (byte) (isIdentify ? 0 : 1)));
        values.add(new FiedValue(110, 0));
        values.add(new FiedValue(29, equip.getGender()));
        if (!isIdentify) {
            values.add(new FiedValue(282, 2));//未鉴定装备能叠加
        }
        values.forEach(value -> linkedHashMap.put(value.getType(), value));
        return linkedHashMap;
    }

    /**
     * 获取装备基础属性
     */
    public static RoleEquipField getBasicAttNew(Equip equip) {
        RoleEquipField roleEquipField = new RoleEquipField();
        roleEquipField.setType((short) 258);
        LinkedHashMap<Short, FiedValue> linkedHashMap = new LinkedHashMap<>();
        NutMap basic = SpringUtils.getBean(AttrService.class).getBasicAttrib(equip.getPosition(), equip.getReq_level());
        basic.forEach((key, value) -> {
            int fieldId = SpringUtils.getBean(AttrService.class).getFiledIdBy(key);
            linkedHashMap.put((short) fieldId, new FiedValue(fieldId, SpringUtils.getBean(AttrService.class).getValue(value)));
        });
        roleEquipField.setField(linkedHashMap);
        return roleEquipField;
    }

    /**
     * 设置共鸣的属性
     */
    public static void setResonanceField(Equip equip, Map.Entry<Short, FiedValue> entry, int upgradeLevel) {
        short fieldId = entry.getKey();
        Attribute attribute = SpringUtils.getBean(AttrService.class).getAttr(fieldId);
        int newValue = ToolsPub.getGongMingField(upgradeLevel, entry.getKey(), equip.getReq_level());
        entry.getValue().setType(fieldId);
        entry.getValue().setVT(attribute.getType());
        entry.getValue().setValue(newValue);
    }

    /**
     * 直接获取装备最终改造属性
     */
    public static LinkedHashMap<Short, RoleEquipField> calcAttribOneKey(short equipLevel, int upgradeLevel, int pos, boolean isPre) {
        LinkedHashMap<Short, RoleEquipField> equipFields = new LinkedHashMap<>();
        Map<String, FiedValue> totalAttrib = new HashMap<>();
        if (isPre) {
            upgradeLevel++;
        }
        for (int level = 1; level <= upgradeLevel; level++) {
            Map<String, FiedValue> resultAttrib = calcAttrib(pos, equipLevel, level);
            resultAttrib.forEach((key, value) -> {
                FiedValue attrib = totalAttrib.get(key);
                if (attrib == null) {
                    totalAttrib.put(key, new FiedValue(value.getType(), value.getValue()));
                } else {
                    AttrService attrService = SpringUtils.getBean(AttrService.class);
                    attrib.setValue(attrService.getValue(value.getValue()) + attrService.getValue(attrib.getValue()));
                }
            });
        }
        RoleEquipField roleEquipField = new RoleEquipField();
        roleEquipField.setType((short) 2562);
        totalAttrib.values().forEach(value -> roleEquipField.getField().put(value.getType(), value));
        equipFields.put(roleEquipField.getType(), roleEquipField);
        return equipFields;
    }

    /**
     * 获取武器单次的改造属性
     */
    private static Map<String, FiedValue> calcAttrib(int equipType, int equipLevel, int rebuildLevel) {
        Map<String, FiedValue> resultAttrib = new HashMap<>();
        if (rebuildLevel > 12 || rebuildLevel <= 0) {
            return resultAttrib;
        }
        if (rebuildLevel > 4) {
            resultAttrib.put("all_attrib", new FiedValue(220, 3));
        }
        if (equipType == Const.WEAPON) {
            resultAttrib.put("phy_power", new FiedValue(3, (int) Math.floor((0.38 * FormulaUtil.getStdAttack(equipLevel + 5)) / 5)));
            resultAttrib.put("mag_power", new FiedValue(10, (int) Math.floor((0.38 * FormulaUtil.getStdAttack(equipLevel + 5)) / 5 * 0.75)));
        } else if (equipType == Const.HELMET || equipType == Const.ARMOR || equipType == Const.BOOT) {
            if (rebuildLevel > 4 && equipLevel >= 100) {
                resultAttrib.put("max_life", new FiedValue(7, (int) Math.floor(FormulaUtil.getStdLife(equipLevel + 5) * 0.0152)));
            }
            resultAttrib.put("def", new FiedValue(8, (int) Math.floor(FormulaUtil.getStdDefense(equipLevel + 5) * 4 / 15)));
        }
        return resultAttrib;
    }

    /**
     * 随机取装备属性ID
     */
    public static int getRandomFieldId(int pos) {
        Random random = new Random();
        int index;
        int result;
        if (pos == 1) {
            // 掉武器
            index = random.nextInt(Weapons.size());
            result = Weapons.get(index);
        } else if (pos == 2) {
            // 帽子
            index = random.nextInt(Hats.size());
            result = Hats.get(index);
        } else if (pos == 3) {
            // 衣服
            index = random.nextInt(Clothes.size());
            result = Clothes.get(index);
        } else {
            // 鞋子
            index = random.nextInt(Shoes.size());
            result = Shoes.get(index);
        }
        return result;
    }

    /**
     * 推送装备信息到客户端
     */
    private static void pushEquipInfo(Role role, RoleEquip roleEquip) {
        RespIconCartoon respIconCartoon = new RespIconCartoon();
        respIconCartoon.setName(roleEquip.getName());
        respIconCartoon.setRightNow((short) 1);
        respIconCartoon.setParam(roleEquip.getId() + "");
        MessagePusher.pushMessage(role, respIconCartoon);
    }


    public static FiedValue randomField(Equip equip, RoleEquip roleEquip, RoleEquip oldRoleEquip, boolean isX5) {
        if (equip.getReq_level() < 80) {
            return null;
        }
        LinkedHashMap<Short, FiedValue> linkedHashMap;
        LinkedHashMap<Short, FiedValue> posLinkedHashMap;

        LinkedHashMap<Short, FiedValue> pinkLinkedHashMap;
        LinkedHashMap<Short, FiedValue> pinkPosLinkedHashMap;
        if (oldRoleEquip == null) {
            {
                RoleEquipField roleEquipField = roleEquip.getFields().get((short) 514);//属性
                if (roleEquipField == null) {
                    roleEquipField = new RoleEquipField();
                    roleEquipField.setType((short) 514);
                    roleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
                }
                linkedHashMap = roleEquipField.getField();//属性
                if (linkedHashMap == null) {
                    linkedHashMap = new LinkedHashMap<>();
                    roleEquipField.setField(linkedHashMap);
                }

                RoleEquipField posRoleEquipField = roleEquip.getFields().get((short) 5378);//属性位置
                if (posRoleEquipField == null) {
                    posRoleEquipField = new RoleEquipField();
                    posRoleEquipField.setType((short) 5378);
                    roleEquip.getFields().put(posRoleEquipField.getType(), posRoleEquipField);
                }
                posLinkedHashMap = posRoleEquipField.getField();//属性位置
                if (posLinkedHashMap == null) {
                    posLinkedHashMap = new LinkedHashMap<>();
                    posRoleEquipField.setField(posLinkedHashMap);
                }
            }

            {
                RoleEquipField roleEquipField = roleEquip.getFields().get((short) 770);//属性
                if (roleEquipField == null) {
                    roleEquipField = new RoleEquipField();
                    roleEquipField.setType((short) 770);
                    roleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
                }
                pinkLinkedHashMap = roleEquipField.getField();//属性
                if (pinkLinkedHashMap == null) {
                    pinkLinkedHashMap = new LinkedHashMap<>();
                    roleEquipField.setField(pinkLinkedHashMap);
                }

                RoleEquipField posRoleEquipField = roleEquip.getFields().get((short) 5634);//属性位置
                if (posRoleEquipField == null) {
                    posRoleEquipField = new RoleEquipField();
                    posRoleEquipField.setType((short) 5634);
                    roleEquip.getFields().put(posRoleEquipField.getType(), posRoleEquipField);
                }
                pinkPosLinkedHashMap = posRoleEquipField.getField();//属性位置
                if (pinkPosLinkedHashMap == null) {
                    pinkPosLinkedHashMap = new LinkedHashMap<>();
                    posRoleEquipField.setField(pinkPosLinkedHashMap);
                }
            }

        } else {
            {
                RoleEquipField roleEquipField = oldRoleEquip.getFields().get((short) 514);//属性
                if (roleEquipField == null) {
                    roleEquipField = new RoleEquipField();
                    roleEquipField.setType((short) 514);
                    oldRoleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
                }
                linkedHashMap = roleEquipField.getField();//属性
                if (linkedHashMap == null) {
                    linkedHashMap = new LinkedHashMap<>();
                    roleEquipField.setField(linkedHashMap);
                }

                RoleEquipField posRoleEquipField = oldRoleEquip.getFields().get((short) 5378);//属性位置
                if (posRoleEquipField == null) {
                    posRoleEquipField = new RoleEquipField();
                    posRoleEquipField.setType((short) 5378);
                    oldRoleEquip.getFields().put(posRoleEquipField.getType(), posRoleEquipField);
                }
                posLinkedHashMap = posRoleEquipField.getField();//属性位置
                if (posLinkedHashMap == null) {
                    posLinkedHashMap = new LinkedHashMap<>();
                    posRoleEquipField.setField(posLinkedHashMap);
                }
            }

            {
                RoleEquipField roleEquipField = oldRoleEquip.getFields().get((short) 770);//属性
                if (roleEquipField == null) {
                    roleEquipField = new RoleEquipField();
                    roleEquipField.setType((short) 770);
                    oldRoleEquip.getFields().put(roleEquipField.getType(), roleEquipField);
                }
                pinkLinkedHashMap = roleEquipField.getField();//属性
                if (pinkLinkedHashMap == null) {
                    pinkLinkedHashMap = new LinkedHashMap<>();
                    roleEquipField.setField(pinkLinkedHashMap);
                }

                RoleEquipField posRoleEquipField = oldRoleEquip.getFields().get((short) 5634);//属性位置
                if (posRoleEquipField == null) {
                    posRoleEquipField = new RoleEquipField();
                    posRoleEquipField.setType((short) 5634);
                    oldRoleEquip.getFields().put(posRoleEquipField.getType(), posRoleEquipField);
                }
                pinkPosLinkedHashMap = posRoleEquipField.getField();//属性位置
                if (pinkPosLinkedHashMap == null) {
                    pinkPosLinkedHashMap = new LinkedHashMap<>();
                    posRoleEquipField.setField(pinkPosLinkedHashMap);
                }
            }
        }
        FiedValue fiedValue = randomOne(equip, linkedHashMap);


        FiedValue randFieldValue = new FiedValue(fiedValue.getType(), fiedValue.getValue());

        if (isX5) {
            fiedValue.setValue(5);
            fiedValue.setType((short) 221);
            fiedValue.setVT((byte) 2);
            linkedHashMap.put(fiedValue.getType(), fiedValue);
        }else {
            linkedHashMap.put(fiedValue.getType(), fiedValue);
        }
        String content = Json.toJson(fiedValue);
        FiedValue posFieldValue = Json.fromJson(FiedValue.class, content);
        posFieldValue.setValue((short) linkedHashMap.size());//属性位置
        posLinkedHashMap.put(fiedValue.getType(), posFieldValue);

        return randFieldValue;
    }

    /**
     * 首饰随机一条属性
     */
    private static FiedValue randomOne(Equip equip, LinkedHashMap linkedHashMap1) {
        Random random = new Random();
        int result = 0;
        while (true) {
            if (equip.getPosition() == 5) {
                // 玉佩11
                result = getRandom(Jade);
                if (attPerfect.contains(result)){
                    result = getRandom(Jade);
                }
            } else if (equip.getPosition() == 4) {
                // 项链
                result = getRandom(Necklace);
                if (attPerfect.contains(result)){
                    result = getRandom(Necklace);
                }
            } else if (equip.getPosition() == 6) {
                // 手镯
                result = getRandom(Bracelet);
                if (attPerfect.contains(result)){
                    result = getRandom(Bracelet);
                }
            }
            short shuxin = (short) result;
            if (linkedHashMap1.get(shuxin) == null) {
                break;
            }
        }
        FiedValue fiedValue = new FiedValue();
        short fieldId = (short) result;
        fiedValue.setType(fieldId);
        AttrService attrService = SpringUtils.getBean(AttrService.class);
        Attribute attribute = attrService.getAttr(fieldId);
        fiedValue.setVT(attribute.getType());
        int min = attrService.getFiledMin(result, equip.getReq_level(), equip.getPosition());
        int max = attrService.getFiledMax(result, equip.getReq_level(), equip.getPosition());

        /**60%概率 min至0.6*max， 30%概率 0.6*max至0.8*max, 10%概率 0.8*max至max*/
        int subMin, subMax;
        int rand = random.nextInt(10000);
        if (1== rand){
            subMin = max * 8 / 10;
            subMax = max;
        }else {
            rand = random.nextInt(10000);
            if (1==rand){
                subMin = max * 6 / 10;
                subMax = max * 8 / 10;
            }else {
                subMin = min;
                subMax = max * 6 / 10;
            }
        }

        int value;
        if (subMax > subMin) {
            value = random.nextInt(subMax - subMin) + subMin + 1;
        } else {
            value = subMax;
        }

        fiedValue.setValue(value);
        return fiedValue;
    }

    private static int getRandom(List<Integer> Jade1){
        Random random = new Random();
        int index = random.nextInt(Jade1.size());
        if (index == 0){
            index = random.nextInt(Jade1.size());
        }
        return Jade1.get(index);
    }
}
